﻿using Hetang.Areas.User.Models.Classes;
using Hetang.Areas.User.Models.Classes.Config;
using Hetang.Models.DataContext;
using Hetang.Models.Helper;
using Hetang.Models.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;

namespace Hetang.Models.Repository
{
    public class DatabaseRepository : IDatabaseRepository
    {
        protected Hetang.Models.DataContext.HetangDataContext db = new DataContext.HetangDataContext(DatabaseHelper.GetDatabaseConnect);

        ISessionRepository _sr = new SessionRepository();

        void IDatabaseRepository.CreateAccount(tbl_Account account)
        {
            db.tbl_Account.InsertOnSubmit(account);

            db.SubmitChanges();

            _sr.SetLoginSession(account,false);
        }

        void IDatabaseRepository.AddCompany(tbl_Company company)
        {
            Type t = company.GetType();

            foreach (PropertyInfo pi in t.GetProperties())
            {
                object value = pi.GetValue(company, null);
                string name = pi.Name;

                if (pi.PropertyType == typeof(string))
                {
                    pi.SetValue(company, string.IsNullOrEmpty(Convert.ToString(value)) ? string.Empty : Convert.ToString(value).Trim(), null);                    
                }
            }

            company.UserId = _sr.GetUserId();
            company.AddDate = DateTime.Now;
            company.ModifyDate = DateTime.Now;
            company.Email = db.tbl_Account.FirstOrDefault(a => a.Id.Equals(_sr.GetUserId())).Email;

            db.tbl_Company.InsertOnSubmit(company);
            db.SubmitChanges();

            _sr.SetCompanyId(company.Id);
        }

        void IDatabaseRepository.AddJob(tbl_Job job)
        {
            db.tbl_Job.InsertOnSubmit(job);
        }

        void IDatabaseRepository.AddResume(tbl_Resume resume)
        {
            Type t = resume.GetType();

            foreach (PropertyInfo pi in t.GetProperties())
            {
                object value = pi.GetValue(resume, null);
                string name = pi.Name;

                switch (name)
                {
                    case "Letter":
                        pi.SetValue(resume, string.IsNullOrEmpty(Convert.ToString(value)) ? string.Empty : Convert.ToString(value).Replace("\r\n", "<br />"), null);
                        break;
                    case "Sex":
                        pi.SetValue(resume, (value.Equals("先生") || value.Equals("小姐")) ? value : "先生", null);
                        break;
                    case "Learn":
                        pi.SetValue(resume, (value.Equals("小学") || value.Equals("初中") || value.Equals("高中") || value.Equals("中专") || value.Equals("大专") || value.Equals("本科") || value.Equals("硕士") || value.Equals("博士")) ? value : "小学", null);
                        break;
                    case "Computer":
                        pi.SetValue(resume, (value.Equals("不懂") || value.Equals("一般") || value.Equals("良好") || value.Equals("熟练") || value.Equals("精通")) ? value : "不懂", null);
                        break;
                    default:
                        if (pi.PropertyType == typeof(string))
                        {
                            pi.SetValue(resume, string.IsNullOrEmpty(Convert.ToString(value)) ? string.Empty : Convert.ToString(value).Trim(), null);
                        }
                        break;
                }                
            }

            resume.UserId = _sr.GetUserId();
            resume.Email = db.tbl_Account.FirstOrDefault(a => a.Id.Equals(_sr.GetUserId())).Email;
            resume.Modify_Date = DateTime.Now;
            resume.Add_Date = DateTime.Now;
            db.tbl_Resume.InsertOnSubmit(resume);
            db.SubmitChanges();

            _sr.SetResumeId(resume.Id);
        }

        void IDatabaseRepository.UpdateResume(tbl_Resume resume)
        {
            var tbl_resume = db.tbl_Resume.FirstOrDefault(r => r.UserId.Equals(_sr.GetUserId()));

            Type inputResumeType = resume.GetType();
            Type resumeType = tbl_resume.GetType();

            foreach (PropertyInfo pi in resumeType.GetProperties())
            {
                object value = pi.GetValue(tbl_resume, null);
                string name = pi.Name;

                if (name.Equals("Id") || name.Equals("UserId") || name.Equals("Add_Date") || name.Equals("Email") || pi.PropertyType == typeof(tbl_Account))
                    continue;
                if (name.Equals("Modify_Date"))
                {
                    pi.SetValue(tbl_resume, DateTime.Now, null);
                    continue;
                }

                foreach (PropertyInfo pi1 in inputResumeType.GetProperties())
                {
                    object value1 = pi1.GetValue(resume, null);
                    string name1 = pi1.Name;

                    if (name.Equals(name1))
                    {
                        switch (name)
                        {
                            case "Letter":
                                pi.SetValue(tbl_resume, value1.ToString().Replace("\r\n", "<br />"), null);
                                break;
                            case "Sex":
                                pi.SetValue(tbl_resume, (value1.Equals("先生") || value1.Equals("小姐")) ? value1 : "先生", null);
                                break;
                            case "Learn":
                                pi.SetValue(tbl_resume, (value1.Equals("小学") || value1.Equals("初中") || value1.Equals("高中") || value1.Equals("中专") || value1.Equals("大专") || value1.Equals("本科") || value1.Equals("硕士") || value1.Equals("博士")) ? value1 : "小学", null);
                                break;
                            case "Computer":
                                pi.SetValue(tbl_resume, (value1.Equals("不懂") || value1.Equals("一般") || value1.Equals("良好") || value1.Equals("熟练") || value1.Equals("精通")) ? value1 : "不懂", null);
                                break;
                            default:
                                if (pi1.PropertyType == typeof(string))
                                {
                                    pi.SetValue(tbl_resume, string.IsNullOrEmpty(Convert.ToString(value1)) ? string.Empty : Convert.ToString(value1).Trim(), null);
                                }
                                else
                                {
                                    pi.SetValue(tbl_resume, value1, null);
                                }
                                break;
                        }
                    }
                }
            }
            db.SubmitChanges();
        }

        void IDatabaseRepository.InsertJob(tbl_Job job)
        {
            Type t = job.GetType();

            foreach (PropertyInfo pi in t.GetProperties())
            {
                object value = pi.GetValue(job, null);
                string name = pi.Name;

                if (name.Equals("OtherDemand"))
                {
                    pi.SetValue(job, string.IsNullOrEmpty(Convert.ToString(value)) ? string.Empty : Convert.ToString(value).Replace("\r\n", "<br />"), null);
                    continue;
                }

                if (pi.PropertyType == typeof(string))
                {
                    pi.SetValue(job, string.IsNullOrEmpty(Convert.ToString(value)) ? string.Empty : Convert.ToString(value).Trim(), null);
                }
            }

            job.CompanyId = _sr.GetCompanyId();
            job.AddDate = DateTime.Now;
            job.UpdateDate = DateTime.Now;
            job.ValidDate = DateTime.Now.AddMonths(1);

            db.tbl_Job.InsertOnSubmit(job);

            db.SubmitChanges();

            var company = db.tbl_Company.SingleOrDefault(c => c.UserId.Equals(_sr.GetUserId()));
            if (!string.IsNullOrEmpty(company.Recruit))
            {
                List<dt_Recruit> recruit = JsonHelper.parse<List<dt_Recruit>>(company.Recruit);
                recruit.Add(new dt_Recruit() { id = job.Id, name = job.JobName, urgent = job.Urgent });
                company.Recruit = JsonHelper.stringify(recruit);
            }
            else
            {
                List<dt_Recruit> recruit = new List<dt_Recruit>(){
                    new dt_Recruit{ id = job.Id, name = job.JobName, urgent = job.Urgent }
                };
                company.Recruit = JsonHelper.stringify(recruit);
            }
        }

        int IDatabaseRepository.GetNumsOfJob()
        {
            return db.tbl_Job.Where(j => j.CompanyId.Equals(_sr.GetCompanyId())).Count();
        }

        bool IDatabaseRepository.CheckRepeatOfJob(string jobName)
        {
            return db.tbl_Job.Where(j => j.CompanyId.Equals(_sr.GetCompanyId()) && j.JobName.Equals(jobName.Trim())).Any();
        }

        List<tbl_Job> IDatabaseRepository.GetJobList()
        {
            return db.tbl_Job.Where(j => j.CompanyId.Equals(_sr.GetCompanyId())).ToList();
        }

        tbl_Job IDatabaseRepository.GetJobByJobId(int? id)
        {
            return db.tbl_Job.SingleOrDefault(j => j.Id.Equals(id));
        }

        bool IDatabaseRepository.DeleteJobByJobId(int id)
        {
            try
            {
                tbl_Job job = db.tbl_Job.SingleOrDefault(j => j.Id.Equals(id) && j.CompanyId.Equals(_sr.GetCompanyId()));
                if (job != null)
                {
                    tbl_Job_Recycle recycle = new tbl_Job_Recycle();

                    Type t_job = job.GetType();
                    Type t_recycle = recycle.GetType();

                    foreach (PropertyInfo pi in t_recycle.GetProperties())
                    {
                        object value = pi.GetValue(recycle, null);
                        string name = pi.Name;

                        if (name.Equals("tbl_Company") || name.Equals("tbl_Job_Recycle"))
                        {
                            continue;
                        }

                        if (name.Equals("DeleteDate"))
                        {
                            pi.SetValue(recycle, DateTime.Now, null);
                            continue;
                        }

                        foreach (PropertyInfo pi1 in t_job.GetProperties())
                        {
                            object value1 = pi1.GetValue(job, null);
                            string name1 = pi1.Name;

                            if (name.Equals(name1))
                            {
                                pi.SetValue(recycle, value1, null);
                            }
                        }
                    }

                    db.tbl_Job.DeleteOnSubmit(job);

                    db.tbl_Job_Recycle.InsertOnSubmit(recycle);

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

        tbl_Account IDatabaseRepository.GetAccountByUserName()
        {
            return db.tbl_Account.FirstOrDefault(a => a.UserName.Equals(Convert.ToString(HttpContext.Current.Session["username"])));
        }

        tbl_Account IDatabaseRepository.GetAccountByEmail(string email)
        {
            return db.tbl_Account.FirstOrDefault(a => a.Email.Equals(email));
        }

        tbl_Company IDatabaseRepository.GetCompanyByAccountId()
        {
            return db.tbl_Company.FirstOrDefault(c => c.UserId.Equals(_sr.GetUserId()));
        }

        string IDatabaseRepository.GetCompanyDepartment()
        {
            return db.tbl_Company.FirstOrDefault(c => c.UserId.Equals(_sr.GetUserId())).Department;
        }

        tbl_Company IDatabaseRepository.GetCompanyById()
        {
            return db.tbl_Company.FirstOrDefault(c => c.Id.Equals(_sr.GetCompanyId()));
        }

        tbl_Resume IDatabaseRepository.GetResume()
        {
            return db.tbl_Resume.FirstOrDefault(s => s.UserId.Equals(_sr.GetUserId()));
        }

        tbl_Resume IDatabaseRepository.GetResumeById(int resumeId)
        {
            return db.tbl_Resume.FirstOrDefault(s => s.Id.Equals(resumeId));
        }

        int IDatabaseRepository.GetResumeId()
        {
            var resume = db.tbl_Resume.SingleOrDefault(s => s.UserId.Equals(_sr.GetUserId()));
            if (resume != null)
                return resume.Id;
            else
                return 0;
        }

        int IDatabaseRepository.GetCompanyId()
        {
            var company = db.tbl_Company.SingleOrDefault(c => c.UserId.Equals(_sr.GetUserId()));
            if (company != null)
                return company.Id;
            else
                return 0;
        }        

        void IDatabaseRepository.UpdateCompany(tbl_Company company)
        {
            var tbl_company = db.tbl_Company.SingleOrDefault(c => c.UserId.Equals(_sr.GetUserId()));

            Type inputCompanyType = company.GetType();
            Type companyType = tbl_company.GetType();

            foreach (PropertyInfo pi in companyType.GetProperties())
            {
                object value = pi.GetValue(tbl_company, null);
                string name = pi.Name;

                if (name.Equals("Id") || name.Equals("UserId") || name.Equals("AddDate") || pi.PropertyType == typeof(tbl_Account))
                    continue;
                if (name.Equals("ModifyDate"))
                {
                    pi.SetValue(tbl_company, DateTime.Now, null);
                    continue;
                }

                foreach (PropertyInfo pi1 in inputCompanyType.GetProperties())
                {
                    object value1 = pi1.GetValue(company, null);
                    string name1 = pi1.Name;

                    if (name.Equals(name1))
                    {                        
                        if (name.Equals("Introduce"))
                        {
                            pi.SetValue(tbl_company, value1.ToString().Replace("\r\n", "<br />"), null);
                            continue;
                        }

                        if (pi1.PropertyType == typeof(string))
                        {
                            pi.SetValue(tbl_company, string.IsNullOrEmpty(Convert.ToString(value1)) ? string.Empty : Convert.ToString(value1).Trim(), null);                            
                        }
                        else
                        {
                            pi.SetValue(tbl_company, value1, null);
                        }
                    }
                }                
            }

            db.SubmitChanges();
        }

        string IDatabaseRepository.GetEmail()
        {
            return db.tbl_Account.FirstOrDefault(a => a.Id.Equals(_sr.GetUserId())).Email;
        }

        tbl_EmailCode IDatabaseRepository.GetLastHandleEmailCode(EmailType emailType)
        {
            return db.tbl_EmailCode.FirstOrDefault(e => e.Email.Equals(_sr.GetEmail()) && ((DateTime.Now - e.CreateDate).TotalMinutes <= 2) && e.HandleType.Equals(emailType.ToString()));
        }

        void IDatabaseRepository.InsertEmailCode(tbl_EmailCode emailCode)
        {
            db.tbl_EmailCode.InsertOnSubmit(emailCode);
            db.SubmitChanges();
        }

        void IDatabaseRepository.Save()
        {
            db.SubmitChanges();
        }
    }
}